﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using XukaShop.Common;
using XukaShop.Dao;
using XukaShop.Models.ConcertModel;
using XukaShop.Models.Entities;

namespace XukaShop.Biz
{
    public class ProductBiz
    {
        private ProductDao _productDao = new ProductDao();

        /// <summary>
        /// Get all products in DB
        /// </summary>
        /// <returns></returns>
        public List<ProductConcert> GetAllProduct()
        {
            return _productDao.GetAllProduct();
        }

        /// <summary>
        /// Get a product by productId
        /// </summary>
        /// <param name="productCode"></param>
        /// <returns></returns>
        public ProductConcert GetProductByCode(string productCode)
        {
            return _productDao.GetProductByCode(productCode);
        }

        /// <summary>
        /// Get Product information by Name
        /// </summary>
        /// <param name="productName"></param>
        /// <returns></returns>
        public ProductConcert GetProductByName(string productName)
        {
            return _productDao.GetProductByName(productName);
        }

        /// <summary>
        /// Get list products are new
        /// </summary>
        /// <returns></returns>
        public List<ProductConcert> GetListNewProduct()
        {
            return _productDao.GetListNewProduct();
        }

        /// <summary>
        /// Get list products are comming soon
        /// </summary>
        /// <returns></returns>
        public List<ProductConcert> GetListCommingSoonProduct()
        {
            return _productDao.GetListCommingSoonProduct();
        }

        /// <summary>
        /// Get list Product Size by product code
        /// </summary>
        /// <param name="productCode"></param>
        /// <returns></returns>
        public List<ProductSize> GetListProductSize(string productCode)
        {
            return _productDao.GetListProductSize(productCode);
        }

        /// <summary>
        /// Get Product Size by ProductSizeId
        /// </summary>
        /// <param name="productSizeId"></param>
        /// <returns></returns>
        public ProductSize GetProductSizeById(int productSizeId)
        {
            return _productDao.GetProductSizeById(productSizeId);
        }

        /// <summary>
        /// Get list product's image by product code
        /// </summary>
        /// <param name="productCode"></param>
        /// <returns></returns>
        public List<ProductImageConcert> GetListProductImageConcertByCode(string productCode)
        {
            return _productDao.GetListProductImageConcertByCode(productCode);
        }

        /// <summary>
        /// Create new product
        /// </summary>
        /// <param name="productEnt"></param>
        /// <returns></returns>
        public bool CreateProduct(Product productEnt)
        {
            return _productDao.CreateProduct(productEnt);
        }

        /// <summary>
        /// Edit a Product
        /// </summary>
        /// <param name="brandModel"></param>
        /// <returns></returns>
        public bool EditProduct(Product productEnt)
        {
            return _productDao.EditProduct(productEnt);
        }

        /// <summary>
        /// Save product information
        /// </summary>
        /// <param name="productEnt"></param>
        /// <param name="isUpdate"></param>
        /// <returns></returns>
        public bool SaveProduct(Product productEnt, bool isUpdate)
        {
            if (isUpdate)
            {
                return this.EditProduct(productEnt);
            }
            productEnt.ProductCode = this.GenerateProductCode(productEnt.GenderId);
            return this.CreateProduct(productEnt);
        }

        /// <summary>
        /// Delete a Product
        /// </summary>
        /// <param name="brandId"></param>
        /// <returns>Id of brand</returns>
        public bool DeleteProduct(string productCode, DirectoryInfo originalDirectory)
        {
            var isSuccessDelete = _productDao.DeleteProduct(productCode);
            if (isSuccessDelete)
            {
                List<ProductImage> lstProductImage = new List<ProductImage>();
                lstProductImage = _productDao.GetListProductImageByCode(productCode);

                // Delete all image of a product in ProductImage table
                var isSuccessDeleteImage = _productDao.DeleteAllProductImage(productCode);
                if (isSuccessDeleteImage)
                {
                    // Delete all image in server folder
                    var isDeleteImageServerSuccess = this.DeleteAllImageInServer(productCode, originalDirectory, lstProductImage);
                    if (isDeleteImageServerSuccess)
                    {
                        // Delete all location of product in ProductLocation table
                        return _productDao.DeleteProductLocation(productCode);
                    }
                }
            }
            return isSuccessDelete;
        }

        /// <summary>
        /// Delete all product image in Databased
        /// </summary>
        /// <param name="productCode"></param>
        /// <returns></returns>
        public bool DeleteAllProductImage(string productCode)
        {
            return _productDao.DeleteAllProductImage(productCode);
        }

        /// <summary>
        /// Delete all image of a product in server
        /// </summary>
        /// <param name="productCode"></param>
        /// <param name="originalDirectory"></param>
        /// <param name="lstProductImage"></param>
        /// <returns></returns>
        public bool DeleteAllImageInServer(string productCode, DirectoryInfo originalDirectory, List<ProductImage> lstProductImage)
        {
            try
            {
                var folderImage = string.Empty;
                if (productCode.Contains(CommonConst.MALE_PREFIX))
                {
                    folderImage = CommonConst.MALE_PREFIX;
                }
                else
                {
                    folderImage = CommonConst.FEMALE_PREFIX;
                }
                string pathString = System.IO.Path.Combine(originalDirectory.ToString(), folderImage);

                foreach (var productImage in lstProductImage)
                {
                    // Delete file in folder
                    var path = string.Format("{0}\\{1}", pathString, productImage.Image);
                    System.IO.File.Delete(path);
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// Save Product Size
        /// </summary>
        /// <param name="lstProductSizeId"></param>
        /// <param name="productCode"></param>
        /// <returns></returns>
        public bool SaveProductSize(string strProductSizeId, string productCode)
        {
            List<string> lstProductSizeId = strProductSizeId.Split(',').ToList();
            return _productDao.SaveProductSize(lstProductSizeId, productCode);
        }

        /// <summary>
        /// Update Product Size
        /// </summary>
        /// <param name="productSizeEnt"></param>
        /// <returns></returns>
        public bool UpdateProductSize(ProductSize productSizeEnt)
        {
            if (productSizeEnt.Quantity == 0)
            {
                productSizeEnt.Status = CommonConst.PRODUCT_SIZE_NOTAVAILABLE;
            }
            else
            {
                productSizeEnt.Status = CommonConst.PRODUCT_SIZE_AVAILABLE;
            }
            return _productDao.UpdateProductSize(productSizeEnt);
        }

        /// <summary>
        /// Create product location based on product code
        /// </summary>
        /// <param name="lstLocationId"></param>
        /// <param name="productCode"></param>
        /// <returns></returns>
        public bool SaveProductLocation(string strLocationId, string productCode)
        {
            List<string> lstLocationId = strLocationId.Split(',').ToList();
            List<int> lstLocationValue = new List<int>();
            foreach (var locationId in lstLocationId)
            {
                lstLocationValue.Add(Convert.ToInt32(locationId));
            }
            return _productDao.SaveProductLocation(lstLocationValue, productCode);
        }

        /// <summary>
        /// Save an image of a product
        /// </summary>
        /// <param name="productImage"></param>
        /// <returns></returns>
        public bool SaveProductImage(ProductImage productImage)
        {
            return _productDao.SaveProductImage(productImage);
        }

        /// <summary>
        /// Delete an image of a product
        /// </summary>
        /// <param name="productImageId"></param>
        /// <param name="productCode"></param>
        /// <returns></returns>
        public bool DeleteProductImage(string productImageName, string productCode)
        {
            return _productDao.DeleteProductImage(productImageName, productCode);
        }

        /// <summary>
        /// Is existed Product Code in DB
        /// </summary>
        /// <param name="productCode"></param>
        /// <returns></returns>
        public bool IsExistedProductName(string productName, string productCode = "", bool isUpdate = false)
        {
            return _productDao.IsExistedProductName(productName, productCode, isUpdate);
        }

        /// <summary>
        /// Generate the Product Code
        /// </summary>
        /// <param name="genderType"></param>
        /// <returns></returns>
        public string GenerateProductCode(int genderId)
        {
            string prefix = string.Empty;
            string productCodeValue = string.Empty;
            if (genderId == CommonConst.MALE)
            {
                prefix = CommonConst.MALE_PREFIX;
            }
            else
            {
                prefix = CommonConst.FEMALE_PREFIX;
            }
            productCodeValue = prefix + DateTime.Now.ToString("hhmmss");
            return productCodeValue;
        }

        /// <summary>
        /// Get list product image information
        /// </summary>
        /// <param name="strProductImageInfo"></param>
        /// <returns></returns>
        public Dictionary<string, string> GetListProductImageInfor(string strProductImageInfo)
        {
            Dictionary<string, string> dicProductImageInfo = new Dictionary<string, string>();
            List<string> lstProductImageOriginal = new List<string>();
            lstProductImageOriginal = strProductImageInfo.Split(',').ToList();
            foreach (var item in lstProductImageOriginal)
            {
                var productImageInfo = item.Split('/');
                string oldName = productImageInfo[0].Trim('[');
                string newName = productImageInfo[1].Trim(']');
                dicProductImageInfo.Add(oldName, newName);
            }
            return dicProductImageInfo;
        }

        /// <summary>
        /// Remove the file name of deleted file in the string product image information 
        /// </summary>
        /// <param name="strProductImageInfo"></param>
        /// <param name="deletedFileName"></param>
        /// <returns></returns>
        public string RemoveDeletedFileName(string strProductImageInfo, string deletedFileName)
        {
            List<string> lstProductImageOriginal = new List<string>();
            lstProductImageOriginal = strProductImageInfo.Split(',').ToList();
            string newProductImageInfo = string.Empty;
            foreach (var image in lstProductImageOriginal)
            {
                if (!image.Contains(deletedFileName))
                {
                    if (string.IsNullOrEmpty(newProductImageInfo))
                    {
                        newProductImageInfo = image;
                    }
                    else
                    {
                        newProductImageInfo = newProductImageInfo + "," + image;
                    }
                }
            }
            return newProductImageInfo;
        }

        /// <summary>
        /// Count how many image of a ProductCode
        /// </summary>
        /// <param name="productCode"></param>
        /// <returns></returns>
        public int CountProductImageHas(string productCode)
        {
            return _productDao.CountProductImageHas(productCode);
        }

        /// <summary>
        /// Get the file name to save
        /// </summary>
        /// <param name="productCode"></param>
        /// <param name="numberOfImage"></param>
        /// <returns></returns>
        public string GetImageNameToSave(string productCode)
        {
            var nextNumber = this.CountProductImageHas(productCode) + 1;
            return productCode + "_" + nextNumber.ToString();
        }

        /// <summary>
        /// Detech a product is inputed the Size Quantity or not
        /// </summary>
        /// <param name="productCode"></param>
        /// <returns></returns>
        public bool IsInputedSizeQuantity(string productCode)
        {
            return _productDao.IsInputedSizeQuantity(productCode);
        }
    }
}